package com.pug.controller.order;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pug.controller.BaseController;
import com.pug.pojo.Hotel;
import com.pug.pojo.KssUser;
import com.pug.pojo.UserOrder;
import com.pug.service.hotel.HotelServiceImpl;
import com.pug.service.hotel.HotelTypeMiddleServiceImpl;
import com.pug.service.hotel.HotelTypeNumServiceImpl;
import com.pug.service.order.UserOrderServiceImpl;
import com.pug.threadlocal.UserThreadLocal;
import com.pug.vo.OrderPayVo;
import com.pug.vo.UserOrderVo;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.AbstractJavaTypeMapper;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Author: lqm
 * create: 2022/5/8 21:39
 * Lover: lqx
 *
 * @see
 */
@RestController
public class OrderController extends BaseController {
    @Resource
    UserOrderServiceImpl userOrderService;
    @Resource
    HotelTypeMiddleServiceImpl hotelTypeMiddleService;
    @Resource
    HotelTypeNumServiceImpl hotelTypeNumService;
    @Resource
    HotelServiceImpl hotelService;
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Resource
    RabbitTemplate rabbitTemplate;
    /***
     * 查询出用户的订单（分页查询）
     * @param  userOrderVo
     * @return
     */
    @PostMapping("/user/order/load")
    public Page<UserOrder> findUserOrders(@RequestBody UserOrderVo userOrderVo){
        return userOrderService.findUserOrders(userOrderVo);
    }

    /***
     * 查询订单信息
     * @return
     */
    @PostMapping("/user/status/load")
    public List<Map<String,Object>> selectOrderStatusInfo(){
        return userOrderService.selectOrderStatusInfo();
    }
    /**
     * 下订单（这个时候还没有支付）
     */
    @PostMapping("weixinpay")
    @Transactional  //如果里面扑获了异常，则事务不回滚（默认）
    public void saveOrder(@RequestBody OrderPayVo orderPayVo){
        Boolean aBoolean = stringRedisTemplate.opsForValue().setIfAbsent("myLock", "qixia", 20L, TimeUnit.SECONDS);
        if(aBoolean){
            try{
                //先查询库存是否充足，否则不予购买
                //分布式锁
                int i = hotelTypeNumService.queryStoreByHotelIdAndTypeId(new Long(orderPayVo.getHotelId()), new Long(orderPayVo.getHotelDetailId()));
                if(i>0){
                    int i1 = hotelTypeNumService.deleteNum(new Long(orderPayVo.getHotelId()), new Long(orderPayVo.getHotelDetailId()), 1);
                    if(i1==1){
                        Hotel hotel = hotelService.getById(new Long(orderPayVo.getHotelId()));
                        //生成订单信息（未支付）
                        KssUser user = UserThreadLocal.get();
                        UserOrder userOrder=new UserOrder();
                        userOrder.setUserId(user.getId());userOrder.setAvatar(user.getAvatar());userOrder.setStatus(0);userOrder.setHotelId(new Long(orderPayVo.getHotelId()));
                        userOrder.setHotelImg(hotel.getImg());userOrder.setPaymoney(hotel.getPrice());userOrder.setHotelDetailId(new Long(orderPayVo.getHotelDetailId()));
                        userOrder.setCreateTime(new Date());userOrder.setUpdateTime(new Date());
                        userOrderService.save(userOrder);
                    }
                }
                //向mq发送用户下订单信息，（这是一个死信队列，30分钟用户没有支付，就把用户的订单信息置为-1）
                rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
                // 2: 设置交换机
                rabbitTemplate.setExchange("liu.order.user.exchange_dead_a");
                // 3: 设置路由key
                rabbitTemplate.setRoutingKey("liu.order.user.routing.key_a");
                // 4: 发送消息，设置消息附属信息，信息载体和消息持久化
                rabbitTemplate.convertAndSend(orderPayVo, new MessagePostProcessor() {
                    @Override
                    public Message postProcessMessage(Message message) throws AmqpException {
                        // 获取消息属性对象
                        MessageProperties messageProperties = message.getMessageProperties();
                        // 设置消息的持久化策略
                        messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                        // 设置消息头的属性的对象
                        messageProperties.setHeader(AbstractJavaTypeMapper.DEFAULT_CONTENT_CLASSID_FIELD_NAME, OrderPayVo.class);
                        // 设置额外的参数
                        messageProperties.setHeader("msgtype", "1");
                        // 返回消息实列
                        return message;
                    }
                });
            }
            catch (Exception e){
                e.printStackTrace();
            }
            finally {
                stringRedisTemplate.delete("myLock");
            }
        }
    }

}
